package com.qdxwx.manage.controller.auth;

import com.qdxwx.captcha.Constants;
import com.qdxwx.common.cache.CacheUtils;
import com.qdxwx.common.config.ProjectConfig;
import com.qdxwx.common.constants.CacheConstants;
import com.qdxwx.common.json.AjaxResult;
import com.qdxwx.common.utils.*;
import com.qdxwx.data.service.manager.ManagerService;
import com.qdxwx.data.service.manager.RoleService;
import com.qdxwx.data.service.menu.MenuService;
import com.qdxwx.manage.config.LoginConstants;
import com.qdxwx.manage.controller.BaseController;
import com.qdxwx.manage.support.AsyncManager;
import com.qdxwx.manage.support.SessionUtils;
import com.qdxwx.manage.support.factory.AsyncFactory;
import com.qdxwx.models.manager.Manager;
import com.qdxwx.sms.QdxSmsClient;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.time.LocalDateTime;
import java.util.Set;

/**
 * 登录验证
 * Qdx NetSchool Platform
 * @author qdxwx
 * @updateTime 2022/5/25
 * @description
 */
@Controller
@RequestMapping("/auth")
public class LoginController extends BaseController {

    @Value("${qdxwx.manage-login-type}")
    private String manageLoginType;

    @Autowired
    private ManagerService managerService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private MenuService menuService;

    @GetMapping("/login.html")
    public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap) {
        // 如果是Ajax请求，返回Json字符串。
        if (TKRequest.isAjaxRequest(request)) {
            return TKServlet.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
        }
        mmap.put("version", ProjectConfig.getVersion());
        mmap.put("manageLoginType", manageLoginType);
        return "auth/login";
    }

    @PostMapping("/login.json")
    @ResponseBody
    public AjaxResult codeLogin(HttpServletRequest request, HttpServletResponse response) {
        String loginId = TKString.trim(request.getParameter("loginId"));
        String mobileCode = TKString.trim(request.getParameter("mobileCode"));
        if (!TKString.isMobile(loginId)) {
            return AjaxResult.error("请输入正确的手机号码！");
        }
        if (TKString.isEmpty(mobileCode)) {
            return AjaxResult.error("请输入手机登录码！");
        }
        try {
            CacheUtils.checkMobileCode(loginId, mobileCode);
        } catch (Exception ex) {
            return AjaxResult.error(ex.getMessage());
        }
        // 查询用户信息
        String message;
        Manager manager = managerService.getBySearchName(loginId);
        if (manager == null) {
            message = MessageUtils.message("user.not.exists");
            AsyncManager.me().execute(AsyncFactory.recordManagerLogin(loginId, LoginConstants.LOGIN_FAIL, message));
            return AjaxResult.error(message);
        }
        if (manager.getIsDisabled() > 0) {
            message = MessageUtils.message("user.blocked");
            AsyncManager.me().execute(AsyncFactory.recordManagerLogin(loginId, LoginConstants.LOGIN_FAIL, message));
            return AjaxResult.error(message);
        }
        manager.setLastLoginIp(TKRequest.getIpAddr(request));
        manager.setLastLoginTime(LocalDateTime.now());
        managerService.update(manager);

        Set<String> roles = roleService.getKeys(manager.getManagerId());
        Set<String> perms = menuService.getPermsByManagerId(manager.getManagerId());

        SessionUtils.setSession(request, manager, roles, perms);

        AsyncManager.me().execute(AsyncFactory.recordManagerLogin(loginId, LoginConstants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));

        return AjaxResult.success();
    }


    @PostMapping("/pwd/login.json")
    @ResponseBody
    public AjaxResult pwdLogin(HttpServletRequest request, HttpServletResponse response) {
        String loginId = TKString.trim(request.getParameter("loginId"));
        String ranCode = TKString.trim(request.getParameter("ranCode"));
        String password = TKString.trim(request.getParameter("password"));
        if (!TKString.isMobile(loginId)) {
            return AjaxResult.error("请输入正确的手机号码！");
        }
        if (TKString.isEmpty(ranCode)) {
            return AjaxResult.error("请输入图片验证码！");
        }
        if (TKString.isEmpty(password)) {
            return AjaxResult.error("请输入账号密码！");
        }
        String vcode = (String) request.getSession().getAttribute(Constants.CAPTCHA_SESSION_KEY);
        if (!TKString.isNotEmpty(vcode)) {
            return AjaxResult.error("图片验证码已失效");
        }
        if (!ranCode.equals(vcode)) {
            return AjaxResult.error("图片验证码错误");
        }
        Manager manager = managerService.getByMobile(loginId);
        if (manager == null) {
            return AjaxResult.error("用户不存在！");
        }
        if (!manager.getLoginPwd().equals(TKConvert.toPWD(password))) {
            return AjaxResult.error("登录密码错误！");
        }
        if (manager.getIsDisabled() > 0) {
            String message = MessageUtils.message("user.blocked");
            AsyncManager.me().execute(AsyncFactory.recordManagerLogin(loginId, LoginConstants.LOGIN_FAIL, message));
            return AjaxResult.error(message);
        }
        manager.setLastLoginIp(TKRequest.getIpAddr(request));
        manager.setLastLoginTime(LocalDateTime.now());
        managerService.update(manager);

        Set<String> roles = roleService.getKeys(manager.getManagerId());
        Set<String> perms = menuService.getPermsByManagerId(manager.getManagerId());

        SessionUtils.setSession(request, manager, roles, perms);

        return AjaxResult.success();
    }

    @GetMapping("/unauth.html")
    public String unauth() {
        return "error/unauth";
    }

    /***
     * 获取登录验证码
     * @return AjaxResult
     */
    @PostMapping("/login/code.json")
    @ResponseBody
    public AjaxResult getLoginCode(HttpServletRequest request) {
        String mobile = TKString.trim(request.getParameter("loginId"));
        String loginRanCode = TKString.trim(request.getParameter("ranCode"));
        if (!TKString.isMobile(mobile)) {
            return AjaxResult.error("请输入正确的手机号码！");
        }
        if (TKString.isEmpty(loginRanCode)) {
            return AjaxResult.error("请输入图片验证码！");
        }
        String vcode = (String) request.getSession().getAttribute(Constants.CAPTCHA_SESSION_KEY);
        if (!TKString.isNotEmpty(vcode)) {
            return AjaxResult.error("图片验证码已失效");
        }
        if (!loginRanCode.equals(vcode)) {
            return AjaxResult.error("图片验证码错误");
        }
        request.getSession().removeAttribute(Constants.CAPTCHA_SESSION_KEY);

        Manager manager = managerService.getByMobile(mobile);
        if (manager == null) {
            return AjaxResult.error("用户不存在！");
        }

        //生成6位随机数
        String mobileCodeNum = (String) CacheUtils.get(CacheConstants.MOBILE_SMS_PRE + manager.getMobile());

        if (!TKString.isEmpty(mobileCodeNum)) {
            return AjaxResult.error("登录码已经发送，如未收到，请5分钟后再次尝试！");
        }

        mobileCodeNum = TKString.getRanNumber(6);
        //把验证码放入缓存
        CacheUtils.set(CacheConstants.MOBILE_SMS_PRE + manager.getMobile(), mobileCodeNum, 300);

        if (request.getServerName().contains("localhost") || request.getServerName().contains("127.0.0.1")) {
            System.out.println("手机验证码:" + mobileCodeNum);
            return AjaxResult.success("验证码已输出在控制台！");
        }

        QdxSmsClient clientQdx = new QdxSmsClient();
        boolean sendState = clientQdx.sendOtherCode(manager.getMobile(), mobileCodeNum);
        if (sendState) {
            return AjaxResult.success("验证码发送成功");
        }
        return AjaxResult.error("验证码发送失败");
    }
}
